#include "surface.h"

class Scanner
{
	public:

		/*** Constructor ***/
		Scanner();

		/*** Get this scanner's value ***/
		unsigned char getMemory();

		/*** Set this scanner's parent surface ***/
		void setSurface(Surface *p_surface);

		/*** Get this scanner's parent surface ***/
		Surface* getSurface();

		/*** Set this scanner's x-coordinate ***/
		void setX(unsigned int px);

		/*** Get this scanner's x-coordinate ***/
		unsigned int getX();

		/*** Set this scanner's y-coordinate ***/
		void setY(unsigned int py);

		/*** Get this scanner's y-coordinate ***/
		unsigned int getY();

		/******* Below are implementations *******/
		/**** Of all BEFLIX scanner operations ***/

		/*** Move to surface and position of B ***/
		void moveToScannerLocation(Scanner beta);

		/*** Move horizontally to X(B) ***/
		void moveHorizontally(Scanner beta);

		/*** Move horizontally to X = n ***/
		void moveHorizontally(unsigned int px);

		/*** Move vertically to Y(B) ***/
		void moveVertically(Scanner beta);

		/*** Move vertically to Y = n ***/
		void moveVertically(unsigned int py);

		/*** Move this scanner up n squares ***/
		void moveUp();

		/*** Move this scanner down n squares ***/
		void moveDown();

		/*** Move this scanner right n squares ***/
		void moveRight();

		/*** Move this scanner left n squares ***/
		void moveLeft();

		/*** Move one square according to n(B) ***/
		void moveAccordingToScanner(Scanner beta);

		/*** Write the number n ***/
		void writeNumber(unsigned char pValue);

		/*** Write the number n(B) ***/
		void writeNumber(Scanner beta);

		/*** Write K(n(B)) ***/
		void writeComplement(Scanner beta);

		/*** Exchange n(A) and n(B) ***/
		void exchangeNumber(Scanner beta);

		/*** Bit-by-bit OR by n(B) ***/
		void orNumber(Scanner beta);

		/*** Bit-by-bit OR n ***/
		void orNumber(unsigned char pValue);

		/*** Bit-by-bit AND by n(B) ***/
		void andNumber(Scanner beta);

		/*** Bit-by-bit AND n ***/
		void andNumber(unsigned char pValue);

		/*** Add n(B) ***/
		void addNumber(Scanner beta);

		/*** Add n ***/
		void addNumber(unsigned char pValue);

		/*** Subtract n(B) ***/
		void subtractNumber(Scanner beta);

		/*** Subtract n ***/
		void subtractNumber(unsigned char pValue);

		/*** Multiply by n(B) ***/
		void multiplyNumber(Scanner beta);

		/*** Multiply by n ***/
		void multiplyNumber(unsigned char pValue);

		/*** Divide by n(B) ***/
		void divideNumber(Scanner beta);

		/*** Divide by n ***/
		void divideNumber(unsigned char pValue);

		/*** Set memory to n(B) ***/
		void setMemory(Scanner beta);

		/*** Set memory to n ***/
		void setMemory(unsigned char pValue);

		/*** Deconstructor ***/
		~Scanner();

	private:

		// The value of this scanner
		unsigned char value;

		// The parent surface of this scanner
		Surface* surface;

		// The x-coordinate of this scanner
		unsigned int x;

		// The y-coordinate of this scanner
		unsigned int y;

		/*** Read the value off the parent surface ***/
		void readValue();

		/*** Write the value onto the parent surface ***/
		void writeValue();
};
